glitter makes SPARQLglitter, un package R pour explorer et collecter des données du web sémantiqueLise Vaudor
21/10/2021
Analyste de données dans un labo de géographie (UMR 5600 Environnement Ville Société)
RĂŽle pĂ©dagogique: aider les collĂšgues Ă utiliser R pour leurs analyses/valorisation (blogđ)
Travail dâappui Ă la recherche => dĂ©veloppement dâoutils dâanalyse, recueil de donnĂ©es du web (API, web-scrapingâŠ)
Projet émergent ENS RECIT
=> R pour lâExploration et la Collecte IntĂ©grĂ©e de Triplets de donnĂ©es
Recrutement de Camille Scheffler (stage M2) et exploration des Wikidata pour deux cas dâĂ©tudes:
En lien (et en parallĂšle) aux cas dâĂ©tudes de Camille, dĂ©veloppement du package R glitter.
đŻ Objectifs:
Promouvoir lâusage (exploration, recueil, analyse) des LOD pour les chercheurs et Ă©tudiants usagers de R, en:
© Camille Scheffler
© Camille Scheffler
|
|
Importance des exemples de requĂȘtes SPARQL pour explorer les bases de donnĂ©es Or, le langage SPARQL est spĂ©cifique Ă
|
|
Un petit projet ⊠(projet Ă©mergent ENS, 20 000 euros sur 3 ans). đ
|
|
SELECT ?film ?filmLabel
WHERE {
?film wdt:P31 wd:Q11424.
SERVICE wikibase:label {
bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en".
}
}
LIMIT 10
query='SELECT ?film ?filmLabel
WHERE {
?film wdt:P31 wd:Q11424.
SERVICE wikibase:label {
bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en".
}
}'
result=purrr::quietly(WikidataQueryServiceR::query_wikidata)(query)
tib=result$rđŻ ChaĂźne de traitement reproductible
| film | filmLabel |
|---|---|
| http://www.wikidata.org/entity/Q372 | We Live in Public |
| http://www.wikidata.org/entity/Q593 | A Gang Story |
| http://www.wikidata.org/entity/Q595 | The Intouchables |
| http://www.wikidata.org/entity/Q1365 | Swept Away |
| http://www.wikidata.org/entity/Q2201 | Kick-Ass |
| http://www.wikidata.org/entity/Q2345 | 12 Angry Men |
Avant:
query='SELECT ?film ?filmLabel WHERE {
?film wdt:P31 wd:Q11424.
SERVICE wikibase:label {
bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en".
}
}
LIMIT 10'
result=WikidataQueryServiceR::query_wikidata(query)
tib=result$rAprĂšs:
tib=spq_init() %>% # Initialise requĂȘte puis
spq_add("?film wdt:P31 wd:Q11424", label="?film") %>% # Ajoute triplet "?film est une instance de film" puis
spq_add("?film wdt:P840 ?loc", label="?loc") %>% # Ajoute triplet "?film a pour localisation narrative ?loc (à étiqueter) puis
spq_language("en,fr") %>% # Affiche les étiquettes en anglais, ou à défaut en français puis
spq_head(n=10) %>% # Sélectionne les 10 premiers résultats puis
send() # Envoie la requĂȘteCombien de films ont la localisation narrative renseignĂ©e dans Wikidata?
tib=spq_init() %>% # Initialise requĂȘte puis
spq_add("?film wdt:P31 wd:Q11424", label="?film") %>% # Ajoute triplet "?film est une instance de film" puis
spq_add("?film wdt:P840 ?loc", label="?loc") %>% # Ajoute triplet "?film a pour localisation narrative ?loc (à étiqueter) puis
spq_summarise(c("?n_films"="COUNT(?film)")) %>% # Résume en comptant le nombre de films puis
send() # Montre la table| n_films |
|---|
| 46879 |
lf_1=spq_init() %>% # Initialise requĂȘte puis
spq_add("?film wdt:P31 wd:Q11424", label="?film") %>% # Ajoute triplet "?film est une instance de film" puis
spq_add("?film wdt:P840 ?loc", label="?loc") %>% # Ajoute triplet "?film a pour localisation narrative ?loc (à étiqueter) puis
spq_add("?loc wdt:P625 ?coords", # Ajoute triplet "?loc a pour coordonnées spatiales ?coords"
within_box=list(southwest=c(3,43), # ... restreins pour que les coordonnées soient comprises
northeast=c(7,47))) %>% # ... dans un cadre défini par ces deux points (S-O et N-E) puis
spq_language("fr") %>% # Etiquette de préférence en français puis
send() # Envoie la requĂȘteCette table comprend 317 lignes. Voici les premiĂšres:
| film | filmLabel | loc | locLabel | coords |
|---|---|---|---|---|
| http://www.wikidata.org/entity/Q86427 | Ă bout de souffle | http://www.wikidata.org/entity/Q23482 | Marseille | Point(5.376388888 43.296666666) |
| http://www.wikidata.org/entity/Q105624 | La Mémoire dans la peau | http://www.wikidata.org/entity/Q23482 | Marseille | Point(5.376388888 43.296666666) |
| http://www.wikidata.org/entity/Q151711 | Marie-Jo et ses deux amours | http://www.wikidata.org/entity/Q23482 | Marseille | Point(5.376388888 43.296666666) |
| http://www.wikidata.org/entity/Q190588 | Love Actually | http://www.wikidata.org/entity/Q23482 | Marseille | Point(5.376388888 43.296666666) |
| http://www.wikidata.org/entity/Q208108 | ArrĂȘte-moi si tu peux | http://www.wikidata.org/entity/Q23482 | Marseille | Point(5.376388888 43.296666666) |
| http://www.wikidata.org/entity/Q215319 | LâImmortel | http://www.wikidata.org/entity/Q23482 | Marseille | Point(5.376388888 43.296666666) |
lf_2=spq_init() %>% # Initialise requĂȘte puis
spq_add("?film wdt:P31 wd:Q11424", label="?film") %>% # Ajoute triplet "?film est une instance de film" puis
spq_add("?film wdt:P840 ?loc", label="?loc") %>% # Ajoute triplet "?film a pour localisation narrative ?loc (à étiqueter) puis
spq_add("?loc wdt:P625 ?coords", # Ajoute triplet "?loc a pour coordonnées spatiales ?coords"
within_box=list(southwest=c(3,43), # ... restreins pour que les coordonnées soient comprises
northeast=c(7,47)))%>% # ... dans un cadre défini par ces deux points (S-O et N-E) puis
spq_add("?film wdt:P18 ?image", required=FALSE) %>% # Ajoute triplet "?film a pour image d'illustration ?image" puis
spq_add("?film wdt:P921 ?subject", # Ajoute triplet "?film a pour sujet ?subject" (info optionnelle)
label="?subject", required=FALSE) %>% # ... étiquette ?subject puis
spq_add("?film wdt:P577 ?date") %>% # Ajoute triplet "?film a été publié à la date ?date puis
spq_mutate(c("?year"="year(?date)")) %>% # Ajoute une variable ?year qui corresond à l'année de ?date puis
spq_language("fr,en") %>% # Etiquette (de préférence en français, à défaut en anglais) puis
send() # Envoie la requĂȘteCette table comprend 594 lignes. Voici les premiĂšres:
##
## SELECT ?film ?filmLabel ?loc ?locLabel ?coords ?image ?subject ?subjectLabel ?date (year(?date) AS ?year)
## WHERE{
##
## ?film wdt:P31 wd:Q11424.
## ?film wdt:P840 ?loc.
## SERVICE wikibase:box {
## ?loc wdt:P625 ?coords.
## bd:serviceParam wikibase:cornerSouthWest 'Point(3 43)'^^geo:wktLiteral.
## bd:serviceParam wikibase:cornerNorthEast 'Point(7 47)'^^geo:wktLiteral.
## }
## OPTIONAL {?film wdt:P18 ?image.}
## OPTIONAL {?film wdt:P921 ?subject.}
## ?film wdt:P577 ?date.
##
## SERVICE wikibase:label { bd:serviceParam wikibase:language "fr,en".}
## }
lf_c=lf_2 %>% # ConsidĂšre lf_2 puis
select(film,ends_with("Label"),coords,image,year) %>% # Sélectionne ces variables (dont "....Label") puis
group_by(film,coords,image,locLabel,filmLabel) %>% # Groupe par ces variables puis
summarise(subjectLabel=stringr::str_c(unique(subjectLabel), # Résume par groupe: le sujet (sur une seule ligne)
collapse=", "), # ... en séparant les éléments par ", "
year=min(year), # ... et l'année comme minimum des années de sortie
.groups="drop") # DégroupeCette table comprend 315 lignes. Voici les premiÚres:
| film | coords | image | locLabel | filmLabel | subjectLabel | year |
|---|---|---|---|---|---|---|
| http://www.wikidata.org/entity/Q100276888 | Point(6.5 44.8) | NA | Alpes françaises | Slalom | sport de compétition, sports industry | 2020 |
| http://www.wikidata.org/entity/Q1033136 | Point(5.376388888 43.296666666) | http://commons.wikimedia.org/wiki/Special:FilePath/Elka%C3%AFm%20Donzelli%20Cabourg%202011.jpg | Marseille | La guerre est déclarée | cancer | 2011 |
| http://www.wikidata.org/entity/Q105624 | Point(3.156666666 46.9925) | NA | Nevers | La Mémoire dans la peau | amnésie | 2002 |
| http://www.wikidata.org/entity/Q105624 | Point(5.376388888 43.296666666) | NA | Marseille | La Mémoire dans la peau | amnésie | 2002 |
| http://www.wikidata.org/entity/Q1061541 | Point(5.376388888 43.296666666) | NA | Marseille | Un prophÚte | crime organisé | 2009 |
| http://www.wikidata.org/entity/Q1062358 | Point(3.086944444 45.779722222) | NA | Clermont-Ferrand | Quand jâĂ©tais chanteur | vieillissement, industrie du spectacle, relation amoureuse, Ăąge moyen, falling in love, human bonding, chansonnier, end of career | 2006 |
đŹ PrĂ©paration dâune fenĂȘtre âpop-upâ (langage html) pour affichage dâinfos dans la carte
lf_m =lf_c %>%
transform_wikidata_coords("coords") %>%
mutate(popup=glue::glue("<h1>{filmLabel}<a href={film} target='_blank'>đ</a></h1>
<li>Lieu: {locLabel}</li>
<li>Année de sortie: {year}</li>")) %>%
mutate(popup=case_when(is.na(image)~popup,
!is.na(image)~glue::glue("{popup}
<img src='{image}' height='200'>"))) %>%
mutate(popup=case_when(is.na(subjectLabel)~popup,
!is.na(subjectLabel)~glue::glue("{popup}
<li>ThĂšmes: {subjectLabel}</li>"))) Un package qui suit quelques principes du tidyverseâŠ
spq_)|
Fonctions de base:
|
|
|
|
FILTRER les résultats renvoyés |
Articles avec âwikidataâ dans le titre (en anglais):
spq_init() %>%
spq_add("?item wdt:P31 wd:Q13442814") %>% # ?item est une instance d'article scientifique
spq_add("?item rdfs:label ?itemTitle") %>% # ?item a pour titre ?itemTitle
spq_filter("contains(lcase(?itemTitle),'wikidata')") %>% # <= ce titre contient (en minuscules) "wikidata"
spq_filter("lang(?itemTitle)='en'") %>% # <= on filtre pour ne garder que les titres en anglais
spq_head(n=5) %>%
send() %>%
show()| item | itemTitle |
|---|---|
| http://www.wikidata.org/entity/Q18507561 | Wikidata: A Free Collaborative Knowledgebase |
| http://www.wikidata.org/entity/Q21503276 | Utilizing the Wikidata system to improve the quality of medical content in Wikipedia in diverse languages: a pilot study |
| http://www.wikidata.org/entity/Q21503284 | Wikidata: A platform for data integration and dissemination for the life sciences and beyond |
| http://www.wikidata.org/entity/Q23712646 | Wikidata as a semantic framework for the Gene Wiki initiative |
| http://www.wikidata.org/entity/Q24074986 | From Freebase to Wikidata: The Great Migration |
|
|
MODIFIER les résultats renvoyés. |
Données sur films, date de sortie ET année de sortie
spq_init() %>%
spq_add("?film wdt:P31 wd:Q11424", label="?film") %>% # ?film est un instance de film
spq_add("?film wdt:P577 ?date") %>% # ?film est sorti Ă la date ?date
spq_mutate(c("?year"="year(?date)")) %>% # <= ajoute variable ?year correspondant à l'année de la date
spq_head(5) %>%
send() %>%
show()| film | filmLabel | date | year |
|---|---|---|---|
| http://www.wikidata.org/entity/Q24340 | Anna Karamazoff | 1991-01-01 | 1991 |
| http://www.wikidata.org/entity/Q24515 | Shaolin | 2011-01-01 | 2011 |
| http://www.wikidata.org/entity/Q24585 | July 14 | 1932-01-01 | 1932 |
| http://www.wikidata.org/entity/Q24585 | July 14 | 1933-01-14 | 1933 |
| http://www.wikidata.org/entity/Q24618 | Jaded | 1998-01-01 | 1998 |
|
|
SELECTIONNER les variables renvoyées |
Données sur films, localisation narrative, date de sortie ET année de sortie
spq_init() %>%
spq_add("?film wdt:P31 wd:Q11424", label="?film") %>% # ?film est une instance de film
spq_add("?film wdt:P577 ?date") %>% # ?film est sorti Ă la date ?date
spq_mutate(c("?year"="year(?date)")) %>% # ?year est l'année correspondant à ?date
spq_select("-?date") %>% # <= on retire la variable ?date
spq_head(5) %>%
send() %>%
show()| film | filmLabel | year |
|---|---|---|
| http://www.wikidata.org/entity/Q24340 | Anna Karamazoff | 1991 |
| http://www.wikidata.org/entity/Q24515 | Shaolin | 2011 |
| http://www.wikidata.org/entity/Q24585 | July 14 | 1932 |
| http://www.wikidata.org/entity/Q24585 | July 14 | 1933 |
| http://www.wikidata.org/entity/Q24618 | Jaded | 1998 |
|
|
ORDONNER les résultats renvoyés. |
Personnes nĂ©es ou habitant Ă New York qui font lâobjet du plus grand nombre dâarticles Wikimedia.
spq_init() %>%
spq_add("?pers wdt:P31 wd:Q5",label="?pers") %>% # ?pers est une instance de personne
spq_add("?pers wdt:P19/wdt:P131* wd:Q60") %>% # qui est née ou est située à New-York
spq_add("?pers wikibase:sitelinks ?sitelinks") %>% # ?personne fait l'objet de n liens dans le projet Wikimedia
spq_arrange(c("desc(?sitelinks)")) %>% # <= classe par ordre décroissant de n
spq_head(n=5) %>%
send() %>%
show()| pers | persLabel | sitelinks |
|---|---|---|
| http://www.wikidata.org/entity/Q22686 | Donald Trump | 280 |
| http://www.wikidata.org/entity/Q4617 | Corbin Bleu | 219 |
| http://www.wikidata.org/entity/Q19848 | Lady Gaga | 178 |
| http://www.wikidata.org/entity/Q33866 | Theodore Roosevelt | 172 |
| http://www.wikidata.org/entity/Q25089 | Woody Allen | 150 |
|
|
GROUPER et RESUMER les résultats renvoyés. |
Communes dâAuvergne-RhĂŽne-Alpes qui ont Ă©tĂ© supprimĂ©es lors de la rĂ©forme territoriale (nombre par dĂ©partement).
tib=spq_init() %>%
spq_add("?com wdt:P31 wd:Q21869758") %>% # ?com est une instance de commune disparue
spq_add("?com wdt:P131* wd:Q18338206") %>% # ?com est située en Auvergne-RhÎne-Alpes
spq_add("?com wdt:P131* ?dep", label="?dep") %>% # ?com est située dans ?dep
spq_add("?dep wdt:P31 wd:Q6465") %>% # ?dep est une instance de département
spq_group_by(c("?dep", "?depLabel")) %>% # Groupe par ?dep et ?depLabel
spq_summarise(c("?ncomsup"="count(?com)")) %>% # Résume: ?ncomsup = nb de ?com
send()
tib %>% show()| dep | depLabel | ncomsup |
|---|---|---|
| http://www.wikidata.org/entity/Q12569 | Loire | 7 |
| http://www.wikidata.org/entity/Q12572 | Haute-Loire | 2 |
| http://www.wikidata.org/entity/Q12745 | Savoie | 54 |
| http://www.wikidata.org/entity/Q46130 | RhĂŽne | 37 |
| http://www.wikidata.org/entity/Q3083 | Ain | 44 |
| http://www.wikidata.org/entity/Q12751 | Haute-Savoie | 17 |
| http://www.wikidata.org/entity/Q2236821 | RhĂŽne-et-Loire | 2 |
| http://www.wikidata.org/entity/Q3113 | Allier | 5 |
| http://www.wikidata.org/entity/Q3148 | ArdĂšche | 6 |
| http://www.wikidata.org/entity/Q3259 | Cantal | 21 |
| http://www.wikidata.org/entity/Q3364 | DrĂŽme | 8 |
| http://www.wikidata.org/entity/Q12694 | Puy-de-DĂŽme | 10 |
| http://www.wikidata.org/entity/Q12559 | IsĂšre | 34 |
| http://www.wikidata.org/entity/Q3120 | Jura | 4 |
Certains Ă©lĂ©ments de syntaxe restent Ă simplifierâŠ
|
Pour lâinstant, beaucoup de longs âstringsâ inspirĂ©s de SPARQL |
Dans lâidĂ©al, une syntaxe qui se rapprocherait le plus possible de: |
Exemple de requĂȘte sur le SPARQL endpoint de dbpedia:
tib=spq_init() %>%
spq_add("?person dbo:birthPlace ?place") %>% # ?personne est née à ?place
spq_add("?person dbo:profession ?job") %>% # ?personne a pour profession ?job
spq_add("?job rdfs:label ?jobLabel") %>% # ?job a pour étiquette ?jobLabel
spq_filter(c("LANG(?jobLabel)='en'")) %>% # Filtre pour ne garder que les étiquettes en anglais
spq_add("?place rdfs:label 'Lyon'@en") %>% # ?place a pour étiquette 'Lyon' (en anglais)
spq_head(10) %>%
send("dbpedia") # Envoie sur le SPARQL endpoint de DBPEDIA Exemple de requĂȘte sur le SPARQL endpoint de hal:
query_doc=spq_init() %>%
spq_add("haldoc:inria-00362381 dcterms:hasVersion ?version") %>% # Ce doc a des versions ?version
spq_add("?version dcterms:title ?title") %>% # ?version a pour titre ?titre
spq_add(". dcterms:creator ?creator") %>% # ...... et pour créateur ?creator
spq_add(". ore:aggregates ?pdf") %>% # ...... et ce lien vers un ?pdf
spq_add("?creator hal:person ?person") %>% # ?creator est une personne ?person
spq_add("?person foaf:name ?name") # ?person a pour nom ?name
tib_doc=send(query_doc,"hal")
tib_doc## version
## 1 <https://data.archives-ouvertes.fr/document/inria-00362381v1>
## 2 <https://data.archives-ouvertes.fr/document/inria-00362381v1>
## 3 <https://data.archives-ouvertes.fr/document/inria-00362381v1>
## 4 <https://data.archives-ouvertes.fr/document/inria-00362381v1>
## 5 <https://data.archives-ouvertes.fr/document/inria-00362381v1>
## title
## 1 "Querying the Semantic Web of Data using SPARQL, RDF and XML"@en
## 2 "Querying the Semantic Web of Data using SPARQL, RDF and XML"@en
## 3 "Querying the Semantic Web of Data using SPARQL, RDF and XML"@en
## 4 "Querying the Semantic Web of Data using SPARQL, RDF and XML"@en
## 5 "Querying the Semantic Web of Data using SPARQL, RDF and XML"@en
## creator
## 1 _:genidnodeID://b614668616
## 2 _:genidnodeID://b614668617
## 3 _:genidnodeID://b614668614
## 4 _:genidnodeID://b614668618
## 5 _:genidnodeID://b614668615
## pdf
## 1 <https://hal.inria.fr/inria-00362381/file/RR-6847.pdf>
## 2 <https://hal.inria.fr/inria-00362381/file/RR-6847.pdf>
## 3 <https://hal.inria.fr/inria-00362381/file/RR-6847.pdf>
## 4 <https://hal.inria.fr/inria-00362381/file/RR-6847.pdf>
## 5 <https://hal.inria.fr/inria-00362381/file/RR-6847.pdf>
## person name
## 1 <https://data.archives-ouvertes.fr/author/62909> HacĂšne Cherfi
## 2 <https://data.archives-ouvertes.fr/author/827904> Fabien Gandon
## 3 <https://data.archives-ouvertes.fr/author/720457> Olivier Corby
## 4 <https://data.archives-ouvertes.fr/author/159177> Khaled Mohamed Khelif
## 5 <https://data.archives-ouvertes.fr/author/327261> Leila Kefi-Khelif
|
| name | url |
|---|---|
| wikidata | https://query.wikidata.org/ |
| dbpedia | https://dbpedia.org/sparql |
| databnf | https://data.bnf.fr/sparql |
| isidore | https://isidore.science/sparql |
| hal | http://sparql.archives-ouvertes.fr/sparql |
âïž DonnĂ©es SIPROJURIS: Le parcours biographique de Gaston,Louis, Henry May (1849 - 1940)
tib=spq_init() %>%
spq_prefix(prefixes=c(sym="http://symogih.org/ontology/", # Préfixe avec sym:
syr="http://symogih.org/resource/")) %>% # Préfixe avec syr:
spq_add("?tyro rdfs:label ?TyRoLabel") %>%
spq_add("?tyin rdfs:label ?TyInLabel") %>%
spq_add("?s ?p syr:Actr56241") %>%
spq_add(". sym:isComponentOf ?info") %>%
spq_add(". sym:hasRoleType ?tyro") %>%
spq_add("?info sym:knowledgeUnitStandardLabel ?infoStandardLabel") %>%
spq_add(". sym:knowledgeUnitStandardDate ?infoStandardDate") %>%
spq_add(". sym:hasKnowledgeUnitType ?tyin") %>%
spq_arrange("?infoStandardDate") %>%
spq_head(n=10) %>%
send(endpoint="http://bhp-publi.ish-lyon.cnrs.fr:8888/sparql") # Envoie sur le sparql endpoint
show(tib)Recrutement de Camille Scheffler (stage M2) et exploration des Wikidata pour deux cas dâĂ©tudes: